#include <SnakeLib/Problem.h>
#include <vector>
#include "MySolver.h"

using namespace snake;
class point
  {
  public:
    size_t x,y,previous;
    point (size_t i_x, size_t i_y, size_t i_previous)
      {
        x=i_x;
         y=i_y;
        previous=i_previous;

      }
    point (const point & i_point)
      {
        x=i_point.x;
        y=i_point.y;
        previous=i_point.previous;
      }
  };
void MySolver::FindHead(const snake::Problem &problem, size_t &x, size_t &y)
  {
  for(unsigned int i=1; i<problem.GetBoard().GetHeight(); ++i)
    {
    for(unsigned int j=1; j<problem.GetBoard().GetWidth(); ++j)
      {
      if(problem.GetBoard().GetCell(i, j) == CELL_SNAKE_HEAD_UP ||
        problem.GetBoard().GetCell(i, j) == CELL_SNAKE_HEAD_DOWN ||
        problem.GetBoard().GetCell(i, j) == CELL_SNAKE_HEAD_RIGHT ||
        problem.GetBoard().GetCell(i, j) == CELL_SNAKE_HEAD_LEFT)
        {
        x = i;
        y = j;
        }
      }
    }

  }

EDirection MySolver::GetNextDirection(snake::Problem problem)
  {
 point head(0,0,0);
  FindHead(problem, head.x, head.y);
  std::vector <point> PossibleMoves(1,head);
  snake::Board index(problem.GetBoard().GetWidth(), problem.GetBoard().GetHeight());
  for(unsigned int j=0;j<index.GetWidth();j++)
  for(unsigned int k=0;k<index.GetWidth();k++)
    {
    index.SetCell(j,k,problem.GetBoard().GetCell(j,k));
    }

  int i=0;
  while (problem.GetBoard().GetCell(PossibleMoves[i].x,PossibleMoves[i].y)!=CELL_FOOD )
    {
      if ( index.GetCell(PossibleMoves[i].x-1,PossibleMoves[i].y)==CELL_EMPTY||
           index.GetCell(PossibleMoves[i].x-1,PossibleMoves[i].y)==CELL_FOOD)
        {
          PossibleMoves.push_back(point(PossibleMoves[i].x-1,PossibleMoves[i].y, i));
           index.SetCell(PossibleMoves[i].x-1,PossibleMoves[i].y,CELL_SNAKE_BODY);
        }
      if ( index.GetCell(PossibleMoves[i].x+1,PossibleMoves[i].y)==CELL_EMPTY||
           index.GetCell(PossibleMoves[i].x+1,PossibleMoves[i].y)==CELL_FOOD)
        {
          PossibleMoves.push_back(point(PossibleMoves[i].x+1,PossibleMoves[i].y, i));    
           index.SetCell(PossibleMoves[i].x+1,PossibleMoves[i].y,CELL_SNAKE_BODY);
        }
      if ( index.GetCell(PossibleMoves[i].x,PossibleMoves[i].y-1)==CELL_EMPTY||
           index.GetCell(PossibleMoves[i].x,PossibleMoves[i].y-1)==CELL_FOOD)
        {
          PossibleMoves.push_back(point(PossibleMoves[i].x,PossibleMoves[i].y-1, i));  
           index.SetCell(PossibleMoves[i].x,PossibleMoves[i].y-1,CELL_SNAKE_BODY);
        }
      if ( index.GetCell(PossibleMoves[i].x,PossibleMoves[i].y+1)==CELL_EMPTY||
           index.GetCell(PossibleMoves[i].x,PossibleMoves[i].y+1)==CELL_FOOD)
        {
          PossibleMoves.push_back(point(PossibleMoves[i].x,PossibleMoves[i].y+1, i));  
           index.SetCell(PossibleMoves[i].x,PossibleMoves[i].y+1,CELL_SNAKE_BODY);
        }
      i++;
    }
  while(PossibleMoves[i].previous!=0)
    {
      i=PossibleMoves[i].previous;
    }
  if (PossibleMoves[i].x==head.x-1)
  return LEFT;
  else
    if (PossibleMoves[i].x==head.x+1)
       return RIGHT;
   else
    if (PossibleMoves[i].y==head.y-1)
       return UP;
   else
    if (PossibleMoves[i].y==head.y+1)
       return DOWN;
  }

EDirection MySolver::Solve(const snake::Problem &problem)
{
// Breaking into a wall



return GetNextDirection(problem);
}

